package cn.yyh.serviceOrder.service.impl;

import cn.yyh.commons.constant.JobTypes;
import cn.yyh.commons.exception.MyException;
import cn.yyh.commons.service.impl.MyBaseServiceImpl;
import cn.yyh.commons.utils.BusinessConstant;
import cn.yyh.commons.utils.CodeGenerateUtils;
import cn.yyh.commons.utils.PageInfo;
import cn.yyh.serviceOrder.client.*;
import cn.yyh.serviceOrder.domain.*;
import cn.yyh.serviceOrder.mapper.AdoptOrderMapper;
import cn.yyh.serviceOrder.mapper.OrderAddressMapper;
import cn.yyh.serviceOrder.quartz.sevice.IQuartzService;
import cn.yyh.serviceOrder.quartz.utils.QuartzJobInfo;
import cn.yyh.serviceOrder.query.AdoptOrderQuery;
import cn.yyh.serviceOrder.service.IAdoptOrderService;
import cn.yyh.serviceOrder.utils.ConvertUtils;
import cn.yyh.serviceOrder.utils.JudgeUtil;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class AdoptOrderServiceImpl extends MyBaseServiceImpl<AdoptOrderMapper, AdoptOrder> implements IAdoptOrderService {
    @Autowired
    private UserClient userClient;
    @Autowired
    private PetClient petClient;
    @Autowired
    private UserAddressClient userAddressClient;
    @Autowired
    private EmpClient empClient;
    @Autowired
    private OrderAddressMapper orderAddressMapper;
    @Autowired
    private PayBillClient payBillClient;
    @Autowired
    private IQuartzService quartzService;


    @Override
    public String submit(Map<String, Object> map, Long id,String token) throws MyException {

        // 1.数据校验
        Integer serviceMethod = Integer.valueOf(map.get("service_method").toString());
        Long addressId = Long.valueOf(map.get("address_id").toString());
        Long payMethod = Long.valueOf(map.get("pay_method").toString());
        Long petId = Long.valueOf(map.get("pet_id").toString());

        JudgeUtil.isNull(serviceMethod,addressId,payMethod,petId);

        // 2.把宠物下架,并绑定userId
        String client = userClient.getByLoginInfoId(id,token);

        User user = ConvertUtils.toUser(ConvertUtils.user(client));
        String byId = petClient.getById(petId, token);
        Pet pet = ConvertUtils.toPet(ConvertUtils.pet(byId));
        pet.setOffsaletime(new Date());
        pet.setState(0);

        pet.setUser_id(user.getId());
        petClient.update(pet,token);

        // 3.生成订单
        AdoptOrder adoptOrder = initAdoptOrder(user, pet);
        baseMapper.save(adoptOrder);

        // 4.生成对应的订单地址
        OrderAddress orderAddress = initOrderAddress(addressId, adoptOrder,token);
        orderAddressMapper.save(orderAddress);

        // 5.支付订单并支付
        PayBill payBill = initPayBill(payMethod, user, adoptOrder);
        String info = payBillClient.save(payBill, token);
        JSONObject jsonObject = JSONObject.parseObject(info).getJSONObject("data").getJSONObject("bill");
        payBill.setId(Long.valueOf(String.valueOf(jsonObject.get("id"))));


        // @TODO 6.超时未支付自动取消
        QuartzJobInfo jobInfo = new QuartzJobInfo();
        jobInfo.setJobName(JobTypes.PAY_OVER_TIME_ADOPT_ORDER + adoptOrder.getId());
        Map<String, Object> m = new HashMap<>();
        m.put("type", JobTypes.PAY_OVER_TIME_ADOPT_ORDER);
        m.put("orderId", adoptOrder.getId());
        jobInfo.setParams(m);
        jobInfo.setFireDate(adoptOrder.getLastPayTime());
        quartzService.addJob(jobInfo);

        return payBillClient.pay(payBill, token);
    }

    private PayBill initPayBill(Long payMethod, User user, AdoptOrder adoptOrder) {
        PayBill payBill = new PayBill();
        payBill.setDigest(adoptOrder.getDigest());
        payBill.setMoney(adoptOrder.getPrice());
        payBill.setUnionPaySn(adoptOrder.getPaySn());
        payBill.setLastPayTime(new Date(System.currentTimeMillis() + 15*1000 * 60));
        payBill.setPayChannel(payMethod);
        payBill.setBusinessType(BusinessConstant.BUSINESS_TYPE_ADOPT);
        payBill.setBusinessKey(adoptOrder.getId());
        payBill.setCreateTime(new Date());
        payBill.setUser_id(adoptOrder.getUser_id());
        payBill.setShop_id(adoptOrder.getShop_id());
        payBill.setNickName(user.getUsername());
        return payBill;
    }

    @Override
    public PageInfo<AdoptOrder> queryByAdmin(AdoptOrderQuery query, Long id,String token) {
        String infoId = empClient.getByLoginInfoId(id, token);
        Employee employee = ConvertUtils.toEmp(ConvertUtils.emp(infoId));
        if (employee.getShopId() != null) {
            query.setShopId(employee.getShopId());
        }
        return super.pageQuery(query);
    }

    @Override
    public PageInfo<AdoptOrder> queryByUser(AdoptOrderQuery query, Long id,String token) {
        String client = userClient.getByLoginInfoId(id,token);
        User user = ConvertUtils.toUser(ConvertUtils.user(client));
        query.setUserId(user.getId());
        return super.pageQuery(query);
    }

    @Override
    public void deleteByQuartz(Long orderId) {
        AdoptOrder order = baseMapper.getById(orderId);
        if (order.getState() == 0) {
            order.setState(-1);
            baseMapper.update(order);
            System.out.println("quartz 触发直接取消订单："+orderId);

        }else if (order.getState() == 2) {
            order.setState(3);
            baseMapper.update(order);
            System.out.println("quartz 触发直接取消订单："+orderId);
        }
    }

    @Override
    public void cancel(Long id) {
        AdoptOrder byId = baseMapper.getById(id);
        if (byId.getState() == 1 ||
                byId.getState() == 2 ||
                byId.getState() == 3) {
            throw new MyException("用户已付款,不能取消,请与用户沟通");
        }
        byId.setState(-1);
        baseMapper.update(byId);
    }

    @Override
    public void successful(Long id) {
        AdoptOrder byId = baseMapper.getById(id);
        byId.setState(2);
        byId.setLastConfirmTime(new Date(System.currentTimeMillis() + 15*1000 * 60));

        QuartzJobInfo jobInfo = new QuartzJobInfo();
        jobInfo.setJobName(JobTypes.CONFIRM_OVER_TIME_ADOPT_ORDER+ byId.getId());
        Map<String, Object> m = new HashMap<>();
        m.put("type", JobTypes.CONFIRM_OVER_TIME_ADOPT_ORDER);
        m.put("orderId", byId.getId());
        jobInfo.setParams(m);
        jobInfo.setFireDate(byId.getLastConfirmTime());
        quartzService.addJob(jobInfo);

        baseMapper.update(byId);
    }

    private OrderAddress initOrderAddress(Long addressId, AdoptOrder adoptOrder,String token) {
        String byId = userAddressClient.getById(addressId, token);
        UserAddress userAddress = ConvertUtils.toUserAddress(ConvertUtils.userAddress(byId));
        OrderAddress orderAddress = new OrderAddress();
        BeanUtils.copyProperties(userAddress,orderAddress);
        orderAddress.setCreateTime(new Date());
        orderAddress.setUpdateTime(new Date());
        orderAddress.setOrder_id(adoptOrder.getId());
        orderAddress.setOrderSn(adoptOrder.getOrderSn());
        return orderAddress;
    }

    private AdoptOrder initAdoptOrder(User user, Pet pet) {
        AdoptOrder adoptOrder = new AdoptOrder();
        adoptOrder.setDigest("[摘要]对{"+ pet.getName()+"}的领养订单！");
        adoptOrder.setPrice(pet.getSaleprice().add(new BigDecimal(10)));
        String orderSn = CodeGenerateUtils.generateOrderSn(user.getId());
        adoptOrder.setPaySn(CodeGenerateUtils.generateUnionPaySn());
        adoptOrder.setOrderSn(orderSn);
        adoptOrder.setLastPayTime(new Date(System.currentTimeMillis()+1000*60*15));
        adoptOrder.setPet_id(pet.getId());
        adoptOrder.setUser_id(user.getId());
        adoptOrder.setShop_id(pet.getShop_id());
        return adoptOrder;
    }
}
